/**
 * FreeZzaphDownloadPlugin.java
 * 
 * FreeZzaph is free software; you can redistribute it
 * and/or modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * FreeZzaph is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.
 */
package freezzaph.plugins;

import java.io.PrintStream;
import java.util.HashMap;

import freezzaph.exceptions.PluginException;

/**
 * <p>The FreeZzaph plugin interface. Any plugin that is to be used with
 * FreeZzaph needs to adhere to this interface.
 * 
 * <p>FreeZzaph plugins will be provided in jar files, conventionally named
 * the name of the plugin + .fzzaph, such as "sexsite.fzzaph".
 * Each jar file can only contain one single plugin, so if you want to
 * create several plugins, you will have to create several jars. Each
 * plugin should only make use of one website.
 * 
 * <p>The jar must contain a manifest file with the field "Plugin-Class".
 * This field must be the full "path" to your plugin class, for instance
 * "com.example.freezaph.plugins.SexSitePlugin". There are no restrictions
 * or rules regarding package names or class names, though it is asked that
 * only "official" FreeZzaph plugins use the "freezzaph" package name, even
 * if it would be possible for others to use the same package name. Even if
 * there are no restrictions on naming, following a naming scheme probably
 * won't hurt. The official FreeZzaph naming scheme for plugins is the name
 * of the plugin + "Plugin", such as "SexSitePlugin".
 * 
 * <p>The plugin class and any and all related classes should under no
 * circumstances throw any exceptions except the {@link PluginException}.
 * Doing so will cause the application to terminate, which will be
 * inconvenient for the user.
 * 
 * @author FreeZzaph
 * @version 1.0
 */
public interface FreeZzaphDownloadPlugin extends FreeZzaphPlugin {
	
	/**
	 * Returns the name of the plugin. Should be all lower case, contain
	 * no whitespace and just be a short identificator, like "sexsite".
	 * This identificator has to be unique, so make sure to pick something
	 * that cannot be mistaken with something else. One should especially
	 * avoid abbreviations like "ss" (for "sexsite").
	 * 
	 * @return the name of the plugin
	 */
	String getPluginName();
	
	/**
	 * Returns the title of the plugin. This can be a longer, more thorough
	 * description, such as "Sex Site.com — The best hardcore action out there!".
	 * 
	 * @return the title of the plugin
	 */
	String getPluginTitle();
	
	/**
	 * Returns a map over category lists. The key for each list should be
	 * the identificator, such as "pictures" and "movies".
	 * 
	 * @return a HashMap containing the plugin's category lists.
	 */
	HashMap<String, CategoryList> getCategoryLists();
	
	/**
	 * <p>If the application is given a command that it does not understand, it
	 * will pass it on to the active plugin before deciding it is an invalid
	 * command. This allows plugin makers to supply the user with extra
	 * plugin-specific commands, which can be used in whatever way the plugin
	 * maker sees fit.
	 * 
	 * <p>If the plugin handled the command (i.e. it was valid) this method
	 * should return <code>true</code>. If it was an invalid command, this
	 * method should return <code>false</code>. A plugin not handling extra
	 * commands should just return <code>false</code> and do nothing more.
	 * 
	 * @param command an array representing the command the user wrote.
	 * <code>command[0]</code> is the command, while the rest (if any) are
	 * parameters for the command.
	 *  
	 * @return <code>true</code> if the plugin handled the command given,
	 * <code>false</code> otherwise.
	 */
	boolean handleCommand(String[] command, PrintStream output);

	/**
	 * <p>If the plugin supports additional commands, this method should return a
	 * list over the commands and what they can be used for. If you wish to have
	 * a consistent look with the application, the list will consist of lines that
	 * are about like so:
	 * 
	 * <p><pre>command &lt;parameter&gt; [&lt;optional parameter&gt;] -- Description of command</pre>
	 * 
	 * <p>If the plugin does not support additional commands, this method should
	 * return <code>null</code>.
	 * 
	 * @return a list over supported commands; if none are supported, <code>null</code>
	 */
	String showHelp();
	
	/**
	 * Using the provided <code>FreeZzaphPluginPreferences</code> object, the plugin
	 * can save settings in a safe way. No other plugins will have access to this node,
	 * and the application itself will not touch it.
	 * 
	 * @param settings the provided preference object.
	 */
	void provideSettings(FreeZzaphPluginPreferences settings);

}
